package weeny.demo;


import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.Point2D;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.Set;

import javax.swing.Box;
import javax.swing.JButton;

import prefuse.Constants;
import prefuse.util.ColorLib;
import prefuse.visual.VisualItem;
import prefuse.visual.VisualTable;

import weeny.cluster.pre.Kmeans;
import weeny.face.LabeledBox;
import weeny.face.LateSpinner;
import weeny.pre.display.MarkerDisplay;

import static weeny.pre.util.IntColor.*;
public class KmeansDemo extends MarkerDisplay{
	public static final String KMEANS = "Kmeans";
	public int NODE_CNT = 1000;
	public int CLUSTER_CNT = 10;
	public Random rand = new Random(System.currentTimeMillis());
	
	public KmeansDemo() {
		final LateSpinner nodeCntSpinner = new LateSpinner();
		nodeCntSpinner.setValue(NODE_CNT);
		nodeCntSpinner.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				NODE_CNT = ((Number)nodeCntSpinner.getValue()).intValue();
				resetNode();
			}
		});
		final LateSpinner clusterCntSpinner = new LateSpinner();
		clusterCntSpinner.setValue(CLUSTER_CNT);
		clusterCntSpinner.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				CLUSTER_CNT = ((Number)clusterCntSpinner.getValue()).intValue();
				cluster();
			}
		});
		LabeledBox paraBox = new LabeledBox("Cluster parameters");
		paraBox.addComp(   "Item count:", nodeCntSpinner);
		paraBox.addComp("Cluster count:", clusterCntSpinner);
		
		JButton resetButton = new JButton("reset");
		resetButton.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				resetNode();
			}
		});
		
		JButton clusterButton = new JButton("(re-)cluster");
		clusterButton.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				cluster();
			}
		});
		
		addWidget(KMEANS, Box.createVerticalStrut(30));
		addWidget(KMEANS, paraBox);
		addWidget(KMEANS, resetButton);
		addWidget(KMEANS, clusterButton);
		
		setSize(800,600);
		showIODisplayTab();
		showItemControlTabInTree();
	}
	
	private void cluster(){
		List<VisualItem> seeds = new ArrayList<VisualItem>();
		VisualTable vt = marker.getVisualNodeTable();
		if (vt.getTupleCount() < CLUSTER_CNT) {
			throw new IllegalStateException("Cluster # is bigger than item #");
		}
		for(int i = 0; i<CLUSTER_CNT; i++){
			seeds.add(vt.getItem(rand.nextInt(vt.getTupleCount())));
		}
		Set<Set> clusters = new Kmeans().cluster(marker.visualNodes(), seeds);
		
		int[] colors = ColorLib.getCategoryPalette(clusters.size());
		int idx = 0;
		for (Set<VisualItem> set : clusters) {
			for (VisualItem visualItem : set) {
				visualItem.setFillColor(colors[idx]);
			}
			idx++;
		}
		m_vis.repaint();
	}
	
	private void resetNode(){
		marker.clear();
		for(int i = 0; i<NODE_CNT; i++){
			double x = rand.nextDouble()*getWidth();
			double y = rand.nextDouble()*getHeight();
			Point2D location = new Point2D.Double(x, y);
			int shape = rand.nextInt(Constants.SHAPE_COUNT); 
			drawShape(location, 3, shape, GREEN).setStrokeColor(BLUE);
		}
		m_vis.repaint();
	}
	
	public static void main(String[] args) {
		KmeansDemo demo = new KmeansDemo();
		demo.showFrame("Kmeans Demo");
	}
}
